/*-----------------------------------------------------------------------------------*/
/*                                                                                   */
/* Copyright (c) 2008 Nuvoton Technology Corporation                                 */
/* All rights reserved                                                               */
/*                                                                                   */
/*-----------------------------------------------------------------------------------*/
/* File Contents:                                                                    */
/*   ps2_keyboard.c                                                                  */
/*                                                                                   */
/* This file contains:                                                               */
/*                                                                                   */
/* Project:                                                                          */
/*                                                                                   */
/* Remark:                                                                           */
/*                                                                                   */
/*                                                                                   */
/*-----------------------------------------------------------------------------------*/

#ifdef ECOS 
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "kapi.h"
#include "diag.h"
#include "wbio.h"
#else
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "wblib.h"
#endif

#include "NUC900_PS2.h"

#ifdef ECOS
#define ps2printf		diag_printf
#define ps2getchar		diag_getc
#else
#define ps2printf		sysprintf
#define ps2getchar		sysGetChar
#endif 

#ifdef ECOS
static cyg_handle_t  	thread_handle;
static cyg_thread 		thread;
#define STACKSIZE		(128*1024)
static UINT8            _Statck[STACKSIZE];
#endif


int port;
PS2_DATA_T rxb[20];

//------------------------- Program -------------------------//
void PS2GetASCIICallBackDemo (void) 
{
	int retval;
	
	retval = ps2Read(port, (PUINT8)&rxb, 1);
	if (retval > 0)
	{
		ps2printf("scan[0x%02x] ascii[0x%02x] %c\n", rxb[0].ucScanCode, rxb[0].ucAsciiCode,
		rxb[0].ucAsciiCode);
	}
}

#ifdef ECOS
void _ps2KeyboardExample (cyg_addrword_t data)
#else
void _ps2KeyboardExample ()
#endif
{
	int retval, ch, i;
	
	ps2printf("\n\nKeyboard Example ...\n");
	
	/*----------------------------*/
	/* Select PS2 channel.        */
	/*----------------------------*/	
	while (1)
	{
		ps2printf("\n Select PS2 channel [0/1]\n");
		ch = ps2getchar();
		if ( (ch != '0') && (ch != '1') )
			continue;
		else
		{
			if (ch == '0')
				port = PS2_PORT0;
			else
				port = PS2_PORT1;	
				
			break;	
		}	
	}
	ps2printf(" Channel[%d] selected\n", port);		
	
	ps2Init();
	retval = ps2Open(port, PS2_KEYBOARD);
	if (retval != 0)
	{
		ps2printf("\n Open PS2 device fail!\n");
		return;	

	}
	
	/*----------------------------*/
	/* Set callback function.     */
	/*----------------------------*/		
	while (1)
	{
		ps2printf("\n Enable callback function ? [y/n]\n");
		ch = ps2getchar();
		if ( (ch != 'y') && (ch != 'n') && (ch != 'Y') && (ch != 'N') )
			continue;
		else
			break;	
	}	
	
	if( (ch == 'n') || (ch == 'N') )
	{
		/*
			Disable callback function example.
		*/	
		ps2printf(" Disable callback function selected\n");		
		retval = ps2Ioctl(port, PS2_IOC_FLUSH_RX_BUFFER, 0, 0);
		if (retval != 0)
		{
			ps2printf("\n Flush Rx buffer fail!\n");
			return;	
		}
		
		/*----------------------------*/
		/* Set Rx operation mode.     */
		/*----------------------------*/
		while (1)
		{
			ps2printf("\n Set Rx operation mode block/non-block [0/1]\n");
			ch = ps2getchar();
			if ( (ch != '0') && (ch != '1') )
				continue;
			else
				break;	
		}	
	
		if (ch == '0')
		{
			ps2printf(" Block mode selected\n");	
			retval = ps2Ioctl(port, PS2_IOC_SET_RX_MODE, PS2_BLOCK, 0);
			if (retval != 0)
				ps2printf("Set block mode failed!\n");
			else
			{
				ps2printf("\nPress 10 keys on keyboard to test\n");
				ps2printf("Start to test\n");				
				while (1)
				{
					retval = ps2Read(port, (PUINT8)&rxb, 10);	
					if (retval > 0)
					{
						for (i = 0; i < 10; i++)
							ps2printf("%d scan[0x%02x] ascii[0x%02x]\n", i + 1, rxb[i].ucScanCode, 
							rxb[i].ucAsciiCode);
					}
				}
			}
		}
		else
		{
			ps2printf(" Non-block mode selected\n");	
			retval = ps2Ioctl(port, PS2_IOC_SET_RX_MODE, PS2_NON_BLOCK, 0);
			if (retval != 0)
				ps2printf("Set block mode failed!\n");
			else
			{
				ps2printf("\nPress any keys on keyboard to test\n");
				ps2printf("Start to test\n");
				while(1)
				{
					retval = ps2Read(port, (PUINT8)&rxb, 1);	
					if (retval > 0)
						ps2printf("scan[0x%02x] ascii[0x%02x] %c\n", rxb[0].ucScanCode, rxb[0].ucAsciiCode,
						rxb[0].ucAsciiCode);
				}
			}				
		}		
	}
	else
	{
		/*
			Enable callback function example.
			Note: Set PS2 Rx non-block mode before execute callback function.
		*/
		ps2printf(" Enable callback function selected\n");
		retval = ps2Ioctl(port, PS2_IOC_SET_RX_MODE, PS2_NON_BLOCK, 0);
		if (retval != 0)
			ps2printf("Set block mode failed!\n");
		else
		{
			ps2printf("\n Start to test.\n");
			ps2printf(" Press any key on HyperTerminal to exit test ...\n");			
			retval = ps2Ioctl(port, PS2_IOC_SET_CALLBACK_FUN, (UINT32)PS2GetASCIICallBackDemo, 0);
			if (retval != 0)
				ps2printf("Install callback function failed!\n");
			else
			{
				ch = ps2getchar();
				ps2printf("\n Stop callback demo\n");
				retval = ps2Ioctl(port, PS2_IOC_DISABLE_CALLBACK_FUN, 0, 0);
			}	
		}
	}
	return;	
}	

int main ()
{


#ifdef ECOS

	cyg_thread_create(20, _ps2KeyboardExample, 0, "ps2keyboard", _Statck, STACKSIZE, &thread_handle, &thread);
	cyg_thread_resume(thread_handle);

#else
	_ps2KeyboardExample();
#endif	
	
	return 0;	
}
